#include "abf.h"

#include <assert.h>
#include <math.h>
#include <stdio.h>
#include <string.h>

typedef struct
{
    const char* name;
    int max_level;
    float score;
} record;

record highscore[] =
{
  { "Ms. John Soda", 4, 23.99 },
  { "Aphex Twin", 17, 19.2 },
};

void put_record(abf_flat_t* flat, const char* name, record* rec)
{
    abf_flat_t* sub = abf_create();
    abf_put_string(sub, "name", rec->name);
    abf_put_sint16(sub, "max_level", rec->max_level);
    abf_put_float(sub, "score", rec->score);
    abf_put_flat(flat, name, sub);
    abf_destroy(sub);
}

void test_record_inorder(abf_flat_t* flat, const char* name, record* rec)
{
    abf_flat_t* sub = abf_get_flat(flat, name);

    /*
    const char * typename = abf_flat_gettypename(abf_flat_gettype(abf_flat_current(sub)));
    printf("%s:%s\n", typename, abf_flat_tostring(abf_flat_current(sub)));
    */
    assert( strcmp(abf_get_string(sub, "name"), rec->name) == 0 );

    /*
    const char * typename = abf_flat_gettypename(abf_flat_gettype(abf_flat_current(sub)));
    printf("%s:%s\n", typename, abf_flat_tostring(abf_flat_current(sub)));
    */
    assert( abf_get_sint16(sub, "max_level") == rec->max_level );

    /*
    const char * typename = abf_flat_gettypename(abf_flat_gettype(abf_flat_current(sub)));
    printf("%s:%s\n", typename, abf_flat_tostring(abf_flat_current(sub)));
    */
    assert( fabs(abf_get_float(sub, "score") - rec->score) < 1.0e-15 );
    abf_destroy (sub);
}

void test_record_outoforder(abf_flat_t* flat, const char* name, record* rec)
{
    abf_flat_t* sub = abf_get_flat(flat, name);
    assert( abf_get_sint16(sub, "max_level") == rec->max_level );
    assert( strcmp(abf_get_string(sub, "name"), rec->name) == 0 );
    assert( fabs(abf_get_float(sub, "score") - rec->score) < 1.0e-15 );
    abf_destroy (sub);
}

void test_mode_switch()
{
    abf_flat_t* flat = abf_create ();
    abf_put_sint8(flat, "multi", 27);
    assert( abf_get_sint8(flat, "multi") == 27 );
    assert( abf_get_sint8(flat, "multi") == 27 );
    abf_put_sint16(flat, "multi-2", 272);
    assert( abf_get_sint8(flat, "multi") == 27 );
    assert( abf_get_sint8(flat, "multi") == 27 );
    assert( abf_get_sint16(flat, "multi-2") == 272 );
    assert( abf_get_sint8(flat, "multi") == 27 );
    abf_destroy(flat);
}

void test_record_inout()
{
    abf_flat_t* flat = abf_create ();
    int i;
    int n= sizeof(highscore)/sizeof(highscore[0]);

    for(i=0;i<n;++i)
        put_record(flat, "entry", &highscore[i]);

    abf_flat_seek(flat,0);
    for(i=0;i<n;++i)
        test_record_inorder(flat, "entry", &highscore[i]);

    for(i=0;i<n;++i)
        test_record_outoforder(flat, "entry", &highscore[i]);

    abf_dump(flat, ABF_NOLIMIT);
    abf_destroy(flat);
}

int main(int argc, char** argv)
{
    test_mode_switch();
    test_record_inout();
    fprintf(stderr, "%s ok\n",argv[0]);
    return 0;
}
